﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;

namespace Amf4Asmx.Web.Handlers
{
    public class WebServiceHandlerFactory : IHttpHandlerFactory
    {
        #region IHttpHandlerFactory Members

        public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
        {
            IHttpHandler result = null;

            // load in from configuration file
            Configuration.ServiceHandlersSection config = System.Configuration.ConfigurationManager.GetSection("amf4asmx") as Configuration.ServiceHandlersSection;
            if (config != null)
            {
                Configuration.ServiceHandlerMapping mapping = config.FindMapping(context.Request.ContentType);
                if (mapping != null)
                {
                    result = GetFactoryProduct(mapping.TypeInternal, context, requestType, url, pathTranslated);
                }

                if (context.Request.Url.Query == "?amf")
                {
                    result = new AmfReflectionHandler();
                }
                else if (result == null)
                {
                    result = GetFactoryProduct(config.TypeInternal, context, requestType, url, pathTranslated);
                }
            }

            return result;
        }

        private IHttpHandler GetFactoryProduct(Type factoryType, HttpContext context, string requestType, string url, string pathTranslated)
        {
            object result = Activator.CreateInstance(factoryType);
            if (result == null)
            {
                return null;
            }
            else if (result is IHttpHandlerFactory)
            {
                IHttpHandlerFactory factory = result as IHttpHandlerFactory;
                return new HandlerWrapper(factory.GetHandler(context, requestType, url, pathTranslated), factory);
            }
            else
            {
                return result as IHttpHandler;
            }
        }

        public void ReleaseHandler(IHttpHandler handler)
        {
            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }
            else if (handler as HandlerWrapper != null)
            {
                (handler as HandlerWrapper).ReleaseHandler();
            }
        }

        #endregion
    }
}
